package mylab.starters.dag.task;

import com.github.rholder.retry.Retryer;
import com.github.rholder.retry.RetryerBuilder;
import com.github.rholder.retry.StopStrategies;
import com.github.rholder.retry.WaitStrategies;

import java.util.Set;
import java.util.concurrent.TimeUnit;

public interface TaskSetting<V> {

    default TaskFailStrategy getTaskFailStrategy() {
        return TaskFailStrategy.BREAK_WHEN_FAIL;
    }

    /**
     * 默认返回值
     */
    default V getDefaultValue() {
        return null;
    }

    /**
     * 获取任务参数
     */
    Set<Object> getParameters();

    /**
     * 超时单位
     */
    default TimeUnit getTimeUnit() {
        return TimeUnit.MILLISECONDS;
    }

    /**
     * 任务终止策略：任务额定时间（包含重试）
     * <p>
     * - 当任务耗时大于额定时间，任务会异常终止
     * - 与任务最大重试次数互斥
     * </p>
     */
    Long getTimeout();

    /**
     * 任务终止策略：任务最大重试次数
     * <p>
     * - 在重试多少后终止任务
     * - 与任务额定时间互斥
     * </p>
     */
    Integer getRetries();

    default Retryer<V> getRetryer() {
        Integer tryTimes = getRetries();
        Long timeout = getTimeout();
        TimeUnit unit = getTimeUnit();
        RetryerBuilder<V> builder = RetryerBuilder.<V>newBuilder()
                .retryIfException()
                .withWaitStrategy(WaitStrategies.noWait());

        if (timeout != null && timeout > 0) {
            // 优先使用超时机制
            builder.withStopStrategy(StopStrategies.stopAfterDelay(timeout, unit));
        } else if (tryTimes != null && tryTimes > 0) {
            // 其次使用重试机制
            builder.withStopStrategy(StopStrategies.stopAfterAttempt(tryTimes));
        }
        return builder.build();
    }
}
